`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: CBICR, Tsinghua Univ.
// Engineer: Hongyi Li 
// 
// Create Date: 2025/01/05 23:20 (Happy Birthday to Hongyi)
// Design Name: 
// Module Name: Accumulator-based ALU
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////

module AccALU
#(
    parameter DataWidth = 'd32
)(
    input                              clk, rst_n,
    input  [DataWidth-1:0]             i_data,
    input  [          2:0]             i_op,
    output [DataWidth-1:0]             o_data
);

reg  [2 * DataWidth-1:0]               acc_reg;

// Input-Related Reg Update
always @(posedge clk) begin
    if (!rst_n) 
        acc_reg <= 0;
    else 
        case (i_op)
            3'b000: acc_reg <= 0;
            3'b001: acc_reg <= acc_reg + {{DataWidth{1'b0}}, i_data};
            3'b010: acc_reg <= acc_reg - {{DataWidth{1'b0}}, i_data};
            3'b011: acc_reg <= acc_reg * {{DataWidth{1'b0}}, i_data};
            3'b100: acc_reg <= acc_reg << {{DataWidth{1'b0}}, i_data};
            3'b101: acc_reg <= acc_reg >> {{DataWidth{1'b0}}, i_data};
            3'b110: acc_reg <= {{DataWidth{1'b0}}, i_data};
            3'b111: acc_reg <= acc_reg;
            default: acc_reg <= acc_reg;
        endcase
end

assign o_data = acc_reg[DataWidth-1:0];

endmodule